package compilers.AST.types;

import compilers.AST.Node;
import compilers.AST.expression.Term;
import compilers.symbolTable.SymbolTableScope;

public class MyInt extends MyType {
	
	private int fValue;
	private TypeSpecifier fConvertTo = null;
	
	public MyInt(String value, int lineNr) {
		super(lineNr);
		fValue = Integer.parseInt(value);
	}
	
	public MyInt(int value) {
		fValue = value;
	}
	
	public void print(int identLevel) {
		println(identLevel, "Int");
		println(identLevel+1, "Value = " + fValue);
	}
	
	public int getResultType(SymbolTableScope currentScope) {
		if(this.fConvertTo != null) {
			return this.fConvertTo.getType(currentScope);
		}
		return TypeSpecifier.INTEGER;
	}
	
	public int getOriginalType(SymbolTableScope currentScope) {
		return TypeSpecifier.INTEGER;
	}
	
	public boolean isConstant() {
		return true;
	}

	public boolean isConstant(SymbolTableScope currentScope) {
		return true;
	}

	public MyType calculateValue(SymbolTableScope currentScope) {
		return this;
	}
	
	public int getValue() {
		return fValue;
	}

	public MyType and(MyType type2) {
		return null;
	}

	public MyType or(MyType type2) {
		return null;
	}
	
	public MyType equalsRel(MyType type2) {
		if (type2 instanceof MyInt) {
			return new MyBool(fValue == ((MyInt) type2).fValue);
		} else {
			return new MyBool(fValue == ((MyFloat) type2).getValue());
		}
	}

	public MyType nequals(MyType type2) {
		if (type2 instanceof MyInt) {
			return new MyBool(fValue != ((MyInt) type2).fValue);
		} else {
			return new MyBool(fValue != ((MyFloat) type2).getValue());
		}
	}

	public MyType less(MyType type2) {
		if (type2 instanceof MyInt) {
			return new MyBool(fValue < ((MyInt) type2).fValue);
		} else {
			return new MyBool(fValue < ((MyFloat) type2).getValue());
		}
	}

	public MyType lessEq(MyType type2) {
		if (type2 instanceof MyInt) {
			return new MyBool(fValue <= ((MyInt) type2).fValue);
		} else {
			return new MyBool(fValue <= ((MyFloat) type2).getValue());
		}
	}

	public MyType greaterEq(MyType type2) {
		if (type2 instanceof MyInt) {
			return new MyBool(fValue >= ((MyInt) type2).fValue);
		} else {
			return new MyBool(fValue >= ((MyFloat) type2).getValue());
		}
	}

	public MyType greater(MyType type2) {
		if (type2 instanceof MyInt) {
			return new MyBool(fValue > ((MyInt) type2).fValue);
		} else {
			return new MyBool(fValue > ((MyFloat) type2).getValue());
		}
	}

	public MyType plus(MyType type2) {
		if (type2 instanceof MyInt) {
			return new MyInt(fValue + ((MyInt) type2).fValue);
		} else {
			return new MyFloat(fValue + ((MyFloat) type2).getValue());
		}
	}

	public MyType minus(MyType type2) {
		if (type2 instanceof MyInt) {
			return new MyInt(fValue - ((MyInt) type2).fValue);
		} else {
			return new MyFloat(fValue - ((MyFloat) type2).getValue());
		}
	}

	public MyType mult(MyType type2) {
		if (type2 instanceof MyInt) {
			return new MyInt(fValue * ((MyInt) type2).fValue);
		} else {
			return new MyFloat(fValue * ((MyFloat) type2).getValue());
		}
	}

	public MyType div(MyType type2) {
		if (type2 instanceof MyInt) {
			return new MyInt(fValue / ((MyInt) type2).fValue);
		} else {
			return new MyFloat(fValue / ((MyFloat) type2).getValue());
		}
	}

	public MyType mod(MyType type2) {
		if (type2 instanceof MyInt) {
			return new MyInt(fValue % ((MyInt) type2).fValue);
		} else {
			return new MyFloat(fValue % ((MyFloat) type2).getValue());
		}
	}

	public MyType negate() {
		return new MyInt(-fValue);
	}

	public String valueToString() {
		return Integer.toString(fValue);
	}
	
	public String toType(int type) {
		if (type == TypeSpecifier.FLOAT) {
			return fValue + ".0";
		}
		return "";
	}
	
	public void setConvertTo(TypeSpecifier type) {
		this.fConvertTo = type;
	}
	
	public boolean isArray(SymbolTableScope currentScope) {
		return false;
	}
	
	public String getArrayIdent(SymbolTableScope currentScope) {
		return null;
	}
}
